import unittest
import sqlite3
import os
import tempfile
from pathlib import Path
import xml.etree.ElementTree as ET
from uma_ukm_extractor import DatabaseManager, XMLParser, HistogramInfo, EnumInfo, UKMEventInfo

class TestDatabaseManager(unittest.TestCase):
    def setUp(self):
        # Create a temporary database
        self.temp_db = tempfile.NamedTemporaryFile(delete=False)
        self.db_path = self.temp_db.name
        self.db_manager = DatabaseManager(self.db_path)
        self.db_manager.connect()
        self.db_manager.create_tables()

    def tearDown(self):
        self.db_manager.close()
        os.unlink(self.db_path)

    def test_insert_histogram_new(self):
        hist = HistogramInfo(
            name="Test.Histogram",
            summary="Test summary",
            units="ms",
            file_path="test/path.xml",
            owners=["owner@example.com"]
        )
        metric_id = self.db_manager.insert_histogram(hist)
        self.assertIsNotNone(metric_id)

        # Verify insertion
        cursor = self.db_manager.conn.cursor()
        cursor.execute("SELECT * FROM metrics WHERE id = ?", (metric_id,))
        row = cursor.fetchone()
        self.assertEqual(row['name'], "Test.Histogram")
        self.assertEqual(row['type'], "histogram")
        self.assertEqual(row['summary'], "Test summary")

        # Verify owner
        cursor.execute("SELECT * FROM metric_owners WHERE metric_id = ?", (metric_id,))
        owner_row = cursor.fetchone()
        self.assertEqual(owner_row['owner_email'], "owner@example.com")

    def test_insert_histogram_update(self):
        # 1. Insert initial histogram
        hist1 = HistogramInfo(
            name="Test.Update",
            summary="Initial summary",
            units="ms",
            file_path="test/path.xml"
        )
        id1 = self.db_manager.insert_histogram(hist1)

        # 2. Insert updated histogram with same name
        hist2 = HistogramInfo(
            name="Test.Update",
            summary="Updated summary",
            units="kb", # Changed units
            file_path="test/new_path.xml" # Changed path
        )
        id2 = self.db_manager.insert_histogram(hist2)

        # 3. Verify ID is preserved
        self.assertEqual(id1, id2)

        # 4. Verify fields are updated
        cursor = self.db_manager.conn.cursor()
        cursor.execute("SELECT * FROM metrics WHERE id = ?", (id1,))
        row = cursor.fetchone()
        self.assertEqual(row['summary'], "Updated summary")
        self.assertEqual(row['units'], "kb")
        self.assertEqual(row['file_path'], "test/new_path.xml")

    def test_insert_enum_update(self):
        # 1. Insert initial enum
        enum1 = EnumInfo(
            name="Test.Enum",
            summary="Initial summary",
            file_path="test/enums.xml",
            values=[(1, "Label1", "Desc1")]
        )
        id1 = self.db_manager.insert_enum(enum1)

        # 2. Insert updated enum
        enum2 = EnumInfo(
            name="Test.Enum",
            summary="Updated summary",
            file_path="test/enums.xml",
            values=[(1, "Label1", "Desc1"), (2, "Label2", "Desc2")]
        )
        id2 = self.db_manager.insert_enum(enum2)

        # 3. Verify ID preserved
        self.assertEqual(id1, id2)

        # 4. Verify update
        cursor = self.db_manager.conn.cursor()
        cursor.execute("SELECT summary FROM metrics WHERE id = ?", (id1,))
        self.assertEqual(cursor.fetchone()['summary'], "Updated summary")

        # Verify values updated (count should be 2)
        cursor.execute("SELECT COUNT(*) FROM enum_values WHERE enum_id = ?", (id1,))
        self.assertEqual(cursor.fetchone()[0], 2)

    def test_insert_ukm_update(self):
        # 1. Insert initial UKM
        ukm1 = UKMEventInfo(
            name="Test.UKM",
            summary="Initial summary",
            file_path="test/ukm.xml"
        )
        id1 = self.db_manager.insert_ukm_event(ukm1)

        # 2. Update
        ukm2 = UKMEventInfo(
            name="Test.UKM",
            summary="Updated summary",
            file_path="test/ukm.xml"
        )
        id2 = self.db_manager.insert_ukm_event(ukm2)

        # 3. Verify ID preserved
        self.assertEqual(id1, id2)

        # 4. Verify update
        cursor = self.db_manager.conn.cursor()
        cursor.execute("SELECT summary FROM metrics WHERE id = ?", (id1,))
        self.assertEqual(cursor.fetchone()['summary'], "Updated summary")


class TestXMLParser(unittest.TestCase):
    def setUp(self):
        self.parser = XMLParser()

    def test_parse_histogram(self):
        xml_content = """
        <histogram-configuration>
        <histograms>
            <histogram name="Test.Histogram" units="ms" expires_after="2024-01-01">
                <owner>owner@example.com</owner>
                <summary>Test summary.</summary>
            </histogram>
        </histograms>
        </histogram-configuration>
        """
        # Create temp file
        with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
            f.write(xml_content)
            temp_path = f.name

        try:
            histograms = self.parser.parse_histogram_file(Path(temp_path))
            self.assertEqual(len(histograms), 1)
            hist = histograms[0]
            self.assertEqual(hist.name, "Test.Histogram")
            self.assertEqual(hist.units, "ms")
            self.assertEqual(hist.owners, ["owner@example.com"])
            self.assertEqual(hist.summary, "Test summary.")
        finally:
            os.unlink(temp_path)

if __name__ == '__main__':
    unittest.main()
